package com.jevons.geo_lib.geo_op;

import com.google.gson.JsonObject;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.plugins.annotation.Symbol;
import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**
 * Copyright 2020 JxGIS
 *
 * @file CommonPointHelper
 * @auth linaisheng
 * Created on 2020/11/26.
 * Description：
 */
public class CommonPointHelper {

    public static final String COMMON_KEY = "commonKey";

    //记录点的索引
    public static final String KEY_POINT_INDEXS = "key_point_index";


    Map<String, Set<CommonPoint>> storeMap = new HashMap<>();

    //feature的唯一标识key字段
    private String featureIdKey;

    public CommonPointHelper(String idKey) {
        this.featureIdKey = idKey;
    }

    public String getFeatureIdKey() {
        return featureIdKey;
    }

    public Symbol getSymbol(List<Symbol> symbols, Point point) {
        for (Symbol symbol : symbols) {

            //因为取交点时point坐标是保留小数点后7位
//            double latitude = Double.parseDouble(String.format("%.7f", symbol.getLatLng().getLatitude()));
//            double longitude = Double.parseDouble(String.format("%.7f", symbol.getLatLng().getLongitude()));
            double latitude = symbol.getLatLng().getLatitude();
            double longitude = symbol.getLatLng().getLongitude();

            if (latitude == point.latitude() && longitude == point.longitude()) {
                return symbol;
            }

        }
        return null;
    }

    public FindSymbolOptions getSymbolOptions(List<SymbolOptions> options, Point point) {
        for (int i = 0; i < options.size(); i++) {
            SymbolOptions option = options.get(i);
            //因为取交点时point坐标是保留小数点后7位
//            double latitude = Double.parseDouble(String.format("%.7f", option.getLatLng().getLatitude()));
//            double longitude = Double.parseDouble(String.format("%.7f", option.getLatLng().getLongitude()));
            double latitude = option.getLatLng().getLatitude();
            double longitude = option.getLatLng().getLongitude();

            if (latitude == point.latitude() && longitude == point.longitude()) {
                return new FindSymbolOptions(i, option);
            }
        }
        return null;
    }



    public Symbol getSymbol(List<Symbol> symbols, Point point, String featureId) {
        for (Symbol symbol : symbols) {
            JsonObject data = (JsonObject) symbol.getData();
            String symbolFeatureId = data.get(featureIdKey).getAsString();
            if (featureId.equals(symbolFeatureId)) {

                //因为取交点时point坐标是保留小数点后7位
//                double latitude = Double.parseDouble(String.format("%.7f", symbol.getLatLng().getLatitude()));
//                double longitude = Double.parseDouble(String.format("%.7f", symbol.getLatLng().getLongitude()));
                double latitude = symbol.getLatLng().getLatitude();
                double longitude = symbol.getLatLng().getLongitude();

                if (latitude == point.latitude()  && longitude == point.longitude()) {
                    return symbol;
                }
            }
        }
        return null;
    }


    private boolean hasPoint(String commonKey, CommonPoint point) {
        if (storeMap.containsKey(commonKey)) {
            Iterator<CommonPoint> iterator = storeMap.get(commonKey).iterator();
            while (iterator.hasNext()) {
                CommonPoint item = iterator.next();
                if (item.featureId.equals(point.featureId)) {
                    return true;
                }
            }
        }
        return false;
    }


    public void addCommonPoint(String commonKey, JsonObject jsonObject) {
        addCommonPoint(commonKey, new CommonPoint(commonKey, featureIdKey, jsonObject));
    }

    private void addCommonPoint(String commonKey, CommonPoint point) {
        if (hasPoint(commonKey, point)) {
            //已存在则不添加
            return;
        }
        if (storeMap.containsKey(commonKey)) {
            Set<CommonPoint> set = storeMap.get(commonKey);
            set.add(point);
        } else {
            Set<CommonPoint> set = new HashSet<>();
            set.add(point);
            storeMap.put(commonKey, set);
        }
    }

    public Set<CommonPoint> getCommonPoint(String commonKey) {
        if (storeMap.containsKey(commonKey)) {
            return storeMap.get(commonKey);
        }
        return null;
    }

    public CommonPoint getCommonPoint(String commonKey, String featureId) {
        if (storeMap.containsKey(commonKey)) {
            Iterator<CommonPoint> iterator = storeMap.get(commonKey).iterator();
            while (iterator.hasNext()) {
                CommonPoint item = iterator.next();
                if (item.featureId.equals(featureId)) {
                    return item;
                }
            }
        }
        return null;
    }

    //获取该feature所有存储的公共点
    public List<CommonPoint> getFeatureCommonPoint(String featureId) {
        Iterator<Set<CommonPoint>> iterator = storeMap.values().iterator();
        List<CommonPoint> commonPoints = new ArrayList<>();
        while (iterator.hasNext()) {
            Iterator<CommonPoint> setIterator = iterator.next().iterator();
            while (setIterator.hasNext()) {
                CommonPoint commonPoint = setIterator.next();
                if (commonPoint.getFeatureId().equals(featureId)) {
                    commonPoints.add(commonPoint);
                    break;
                }
            }
        }
        return commonPoints;
    }




    public Set<CommonPoint> removeCommonPoint(String commonKey) {
       if (storeMap.containsKey(commonKey)) {
           return storeMap.remove(commonKey);
       }
       return null;
    }


    public void clear() {
        storeMap.clear();
    }



    public static class CommonPoint {

        String commonKey;
        String featureId;
        int[] coordinatesIndex;

        private CommonPoint(String commonKey, String featureIdKey, JsonObject data) {
            this.commonKey = commonKey;
            data.addProperty(COMMON_KEY, commonKey);

            String indexStr = data.get(KEY_POINT_INDEXS).getAsString();
            String[] indexs = indexStr.split("-");

            this.featureId = data.get(featureIdKey).getAsString();

            coordinatesIndex = new int[indexs.length];
            for (int i = 0; i < indexs.length; i++) {
                coordinatesIndex[i] = Integer.parseInt(indexs[i]);
            }
        }

        public String getCommonKey() {
            return commonKey;
        }

        public String getFeatureId() {
            return featureId;
        }

        public int[] getCoordinatesIndex() {
            return coordinatesIndex;
        }

        public void setCoordinatesIndex(int[] coordinatesIndex) {
            this.coordinatesIndex = coordinatesIndex;
        }
    }


    public class FindSymbolOptions {

        private int index;
        private SymbolOptions options;

        private FindSymbolOptions(int index, SymbolOptions options) {
            this.index = index;
            this.options = options;
        }

        public int getIndex() {
            return index;
        }

        public SymbolOptions getOptions() {
            return options;
        }

        public JsonObject getData() {
            return (JsonObject) options.getData();
        }

        public boolean hasCommonKey() {
            return getData().has(CommonPointHelper.COMMON_KEY);
        }

        public String getCommonKey() {
            return getData().get(CommonPointHelper.COMMON_KEY).getAsString();
        }

    }

}
